package com.bw.ppjokeplay.mvvm.view

import android.content.*
import android.graphics.Color
import android.media.AudioFormat
import android.net.ConnectivityManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import android.view.SurfaceView
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.ToastUtils
import com.bw.ppjokeplay.R
import com.bw.ppjokeplay.adapter.MessageAdapter
import com.example.livehome.MsgEntity
import com.example.livehome.TextEntity
import com.example.livehome.TopEntity
import com.frank.live.LiveApplication
import com.frank.live.LivePusherNew
import com.frank.live.camera2.Camera2Helper
import com.frank.live.listener.LiveStateChangeListener
import com.frank.live.param.AudioParam
import com.frank.live.param.VideoParam
import com.google.gson.Gson
import com.opensource.svgaplayer.SVGACallback
import com.opensource.svgaplayer.SVGAImageView
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import master.flame.danmaku.controller.DrawHandler
import master.flame.danmaku.danmaku.model.BaseDanmaku
import master.flame.danmaku.danmaku.model.DanmakuTimer
import master.flame.danmaku.danmaku.model.IDanmakus
import master.flame.danmaku.danmaku.model.android.DanmakuContext
import master.flame.danmaku.danmaku.model.android.Danmakus
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser
import master.flame.danmaku.ui.widget.DanmakuView
import org.json.JSONObject
import java.util.concurrent.LinkedBlockingQueue

class LiveActivity : AppCompatActivity(), LiveStateChangeListener,OnNetWorkChangeListener, View.OnClickListener,MsgCallBack {
    private lateinit var DV: DanmakuView
    private var live_surface: SurfaceView?=null
    private lateinit var live_msg_edt: EditText
    private lateinit var live_send_btn: Button
    private lateinit var live_rv: RecyclerView
    private var livePusher: LivePusherNew? = null
    private var isPushing = false
    private var connectionReceiver: ConnectionReceiver? = null
    var messageAdapter: MessageAdapter = MessageAdapter()
    private var create: DanmakuContext?=null
    private var giftQueue = LinkedBlockingQueue<String>()
    private var svgaList = ArrayList<String>()
    private lateinit var live_svga : SVGAImageView
    private lateinit var msgService : WebSocketService
    private var connection: MsgConnection = MsgConnection()
    private var svgaListener = SVGAListerner()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live)
        //初始化SVGA
        SVGAParser.shareParser().init(this)
        //动态获取权限

        //为什么要动态获取权限：
            //Google在 Android 6.0 开始将所有权限分成了正常权限和危险权限。
            // 所以如果应用的 targetSdkVersion >= 23 并且 申请了危险权限
            // 但是仅仅在AndroidManifest 注册是不够的，相关运行时会出错，会提示没有相应的权限。

        //常用危险权限：
            //permission:android.permission.WRITE_CONTACTS 写入联系人
            //permission:android.permission.READ_CONTACTS  读取练习人
            //permission:android.permission.CALL_PHONE 打电话
            //permission:android.permission.READ_CALENDAR 读SD卡
            //permission:android.permission.WRITE_CALENDAR 写SD卡
            //permission:android.permission.CAMERA 相机
            //还有定位等权限....
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(arrayOf(android.Manifest.permission.CAMERA,
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE),100)
        }
        //初始化控件
        initview()
        //注册广播
        registerBroadcast(this)
        //设置音视频格式
        initPusher()
        //初始化SVGA资源
        initSVGA()
        var intent  = Intent(this, WebSocketService::class.java)
        bindService(intent, connection, Context.BIND_AUTO_CREATE)


        live_rv.layoutManager = LinearLayoutManager(this)
        messageAdapter = MessageAdapter()
        live_rv.adapter = messageAdapter


        create = DanmakuContext.create()
        DV.prepare(object : BaseDanmakuParser(){
            override fun parse(): IDanmakus? {
                return Danmakus()
            }
        },create)

        DV.setCallback(object : DrawHandler.Callback {
            override fun prepared() {
                DV.start()
            }

            override fun updateTimer(timer: DanmakuTimer?) {

            }

            override fun danmakuShown(danmaku: BaseDanmaku?) {

            }

            override fun drawingFinished() {

            }

        })
    }

    //初始化svga数据
    private fun initSVGA(){
        svgaList.add("a.svga")
        svgaList.add("b.svga")
        svgaList.add("c.svga")
        svgaList.add("d.svga")
        svgaList.add("e.svga")
        svgaList.add("f.svga")
        svgaList.add("g.svga")
        svgaList.add("h.svga")
        svgaList.add("i.svga")
        svgaList.add("j.svga")
        svgaList.add("k.svga")
        svgaList.add("l.svga")
        svgaList.add("m.svga")
        svgaList.add("n.svga")
        svgaList.add("o.svga")
        svgaList.add("p.svga")
        svgaList.add("q.svga")
        svgaList.add("r.svga")
    }
    fun initPusher() {

        //设置视频
        val width = 640//resolution 高度
        val height = 480          //宽度
        val videoBitRate = 800000//kb/s  比特率
        //什么是比特率：
            //比特率是指每秒传送的比特(bit)数
            //比特率越高，传送的数据越大
            //简单的说就是比特率越高，音、视频的质量就越好，但编码后的文件就越大
        val videoFrameRate = 10//fps/    帧率
        //什么是帧率：
            //是指每秒钟刷新的图片的帧数，也可以理解为图形处理器每秒钟能够刷新几次。
            // 越高的帧速率可以得到更流畅、更逼真的动画。每秒钟帧数(FPS)越多，
            // 所显示的动作就会越流畅。

        val videoParam = VideoParam(width, height, Integer.valueOf(Camera2Helper.CAMERA_ID_FRONT), videoBitRate, videoFrameRate)


        //音频设置
        val sampleRate = 44100//sample rate: Hz采样率
        //什么是采样率：
            //每秒从连续信号中提取并组成离散信号的采样个数，它用赫兹（Hz）来表示
        val channelConfig = AudioFormat.CHANNEL_IN_STEREO//android支持双声道立体声和单声道。MONO单声道，STEREO立体声
        val audioFormat = AudioFormat.ENCODING_PCM_16BIT//编码制式和 采样大小（音频的分辨率：波的纵轴，用8位(一个字节)存储，还是16位(两个字节)存储）

        // 采集来的数据当然使用PCM编码(脉冲代码调制编码，
        // 即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。)
        // android支持的采样大小16bit 或者8bit。当然采样大小越大，那么信息量越多，音质也越高，现在主流的采样大小都是16bit。

        val numChannels = 2//channel number  设置STEREO立体声
        val audioParam = AudioParam(sampleRate, channelConfig, audioFormat, numChannels)

        livePusher = LivePusherNew(this, videoParam, audioParam)
//        livePusher!!.switchCamera()
        livePusher!!.setPreviewDisplay(live_surface!!.holder)
    }
    fun initview(){
        live_surface = findViewById(R.id.live_surface)
        live_msg_edt = findViewById(R.id.live_msg_edt)
        live_send_btn = findViewById(R.id.live_send_btn)
        live_rv = findViewById(R.id.live_rv)
        DV = findViewById(R.id.DV)
        live_svga = findViewById(R.id.live_svga)
        findViewById<Button>(R.id.live_start_btn).setOnClickListener(this)
        findViewById<Button>(R.id.live_stop_btn).setOnClickListener(this)
        live_send_btn.setOnClickListener(this)
        live_svga.clearsAfterStop = true
        live_svga.callback = svgaListener
    }

    //动态注册广播
    // 判断网络状态
    private fun registerBroadcast(networkChangeListener: OnNetWorkChangeListener) {
        connectionReceiver = ConnectionReceiver(networkChangeListener)
        val intentFilter = IntentFilter()
        //当网络发生变化的时候，系统广播会发出值为android.net.conn.CONNECTIVITY_CHANGE这样的一条广播
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
        registerReceiver(connectionReceiver, intentFilter)
    }
    //销毁
    override fun onDestroy() {
        super.onDestroy()
        if (livePusher != null) {
            if (isPushing) {
                isPushing = false
                //关闭
                livePusher?.stopPush()
            }
            //释放
            livePusher!!.release()
        }
        if (connectionReceiver != null) {
            unregisterReceiver(connectionReceiver)
        }
    }
    override fun onError(msg: String?) {

        runOnUiThread(object :Runnable{
            override fun run() {
                //吐司错误信息
                Toast.makeText(LiveApplication.getInstance(),msg,Toast.LENGTH_SHORT).show()
            }
        })
    }

    override fun onNetworkChange() {
        if (livePusher != null && isPushing) {
            livePusher?.stopPush()
            isPushing = false
        }
    }

    override fun onClick(v: View?) {
        var id = v!!.id
        when(id){
            R.id.live_start_btn->{
                //设置推流路径开始直播
                livePusher!!.startPush(LiveConst.LIVE_URL,this)
                isPushing == true
            }
            R.id.live_stop_btn->{
                //结束直播
                livePusher!!.stopPush()
                isPushing = false
            }
            R.id.live_send_btn->{

            }
        }
    }

    override fun msgCall(str: String) {
        //
        if (str .equals("连接成功") ){
            return
        }
        Log.e("ZXY","msgCall"+str)
        var jsonObject = JSONObject(str)
        var msgEntity : MsgEntity?=null
        when(jsonObject.getInt("msgType")){
            //消息
            1 -> {
                msgEntity = Gson().fromJson<TextEntity>(str, TextEntity::class.java)
                var ts=msgEntity as TextEntity
                ToastUtils.showShort(str)
                messageAdapter.data.add(ts.msg!!)
                var a=  messageAdapter.data.size
                messageAdapter.notifyItemInserted(a)

            }
            //弹幕
            2 -> {
                msgEntity = Gson().fromJson<TopEntity>(str, TopEntity::class.java)
                var dm = msgEntity as TopEntity
                val danmaku: BaseDanmaku = create!!.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL)
                danmaku.text = dm.msg
                danmaku.padding = 5
                danmaku.priority = 0
                danmaku.isLive = false
                danmaku.time = DV.currentTime + 1200
                danmaku.textSize = 40f
                danmaku.textColor = Color.RED
                DV.addDanmaku(danmaku)

            }
            //礼物
            3 -> {
                msgEntity = Gson().fromJson<GiftEntity>(str, GiftEntity::class.java)
            }
        }
        Log.e("ZXY","msgCall"+(msgEntity == null))
        runOnUiThread(object : Runnable {
            override fun run() {
                if (msgEntity!!.msgType == 3){
                    var giftEntity:GiftEntity = msgEntity as GiftEntity
                    giftQueue.put(svgaList.get(giftEntity.giftId))
                    if (!TextUtils.isEmpty(svgaList.get(giftEntity.giftId))&&svgaFlag) {
                        var svgaPath = giftQueue.poll()
                        loadAnimation(svgaPath)
                    }
                }
            }
        })
    }
    private fun loadAnimation(str : String) {
        val svgaParser : SVGAParser = SVGAParser.shareParser()
        val name = str
        svgaParser.decodeFromAssets(name, object : SVGAParser.ParseCompletion {
            override fun onComplete(videoItem: SVGAVideoEntity) {
                live_svga.setVideoItem(videoItem)
                live_svga.startAnimation()
//                live_home_svga.stepToFrame(0,true)
            }

            override fun onError() {
                Log.e("ZXY","SVGA->onError()")
            }

        })
    }
    var svgaFlag = true
    inner class SVGAListerner : SVGACallback {

        override fun onFinished() {
            svgaFlag = true
            var str  =giftQueue.poll()
            if (!TextUtils.isEmpty(str))
                loadAnimation(str)
        }

        override fun onPause() {
        }

        override fun onRepeat() {
        }

        override fun onStep(frame: Int, percentage: Double) {
            svgaFlag = false
        }

    }
    inner class MsgConnection : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            var binder : WebSocketService.WebSocketBinder = service as WebSocketService.WebSocketBinder
            msgService = binder.getWebSocketService()
            msgService.setMsgCall(this@LiveActivity)
        }

        override fun onServiceDisconnected(name: ComponentName?) {
        }

    }
}